import { Transform } from 'stream';

// 定义解析状态
enum ParseState {
    NORMAL,          // 正常状态
    SINGLE_QUOTE,    // 单引号字符串中
    DOUBLE_QUOTE,    // 双引号字符串中
    LINE_COMMENT,    // 单行注释中 (--)
    BLOCK_COMMENT    // 多行注释中 (/* */)
}

// 解析器选项
interface ParserOptions {
    escapeBackslash?: boolean; // 是否识别反斜杠转义（默认false）
    includeComments?: boolean;  // 是否保留注释
}

// 解耦的流阅读器 - 处理数据流并将结果转交给处理器
class SQLStreamReader extends Transform {
    private processor: SQLStatementProcessor;
    
    constructor(processor: SQLStatementProcessor, options = {}) {
        super({ ...options, objectMode: true });
        this.processor = processor;
    }

    _transform(chunk: Buffer, encoding: string, callback: () => void): void {
        this.processor.processChunk(chunk.toString());
        callback();
    }

    _flush(callback: () => void): void {
        this.processor.finalize()
            .forEach(stmt => this.push(stmt));
        callback();
    }
}

// SQL 语句处理器 - 核心解析逻辑
class SQLStatementProcessor {
    private buffer = '';
    private current = '';
    private state = ParseState.NORMAL;
    private previousState = ParseState.NORMAL;
    private statements: string[] = [];
    private options: ParserOptions;

    constructor(options: ParserOptions = {}) {
        this.options = {
            escapeBackslash: false,
            includeComments: false,
            ...options
        };
    }

    public processChunk(chunk: string): void {
        this.buffer += chunk;
        this.parseBuffer();
    }

    public finalize(): string[] {
        // 处理剩余内容（非正常结束的语句）
        if (this.buffer.trim().length > 0 || this.current.trim().length > 0) {
            const remaining = this.options.includeComments 
                ? this.current + this.buffer 
                : this.current + this.buffer.replace(/--.*|\/\*[\s\S]*?\*\//g, '');
            
            if (remaining.trim().length > 0) {
                this.statements.push(remaining);
            }
        }
        
        const result = [...this.statements];
        this.reset();
        return result;
    }

    public reset(): void {
        this.buffer = '';
        this.current = '';
        this.statements = [];
        this.state = ParseState.NORMAL;
        this.previousState = ParseState.NORMAL;
    }

    private parseBuffer(): void {
        for (let i = 0; i < this.buffer.length; i++) {
            const char = this.buffer[i];
            const nextChar = this.buffer[i + 1];
            const prevChar = this.buffer[i - 1];
            const isEscape = this.options.escapeBackslash && char === '\\';

            switch (this.state) {
                case ParseState.NORMAL:
                    this.handleNormalState(char, nextChar);
                    break;
                    
                case ParseState.SINGLE_QUOTE:
                    if (this.handleQuoteState('\'', char, nextChar, i)) i++;
                    else if (isEscape && nextChar) i++; // 跳过转义字符
                    else this.current += char;
                    break;
                    
                case ParseState.DOUBLE_QUOTE:
                    if (this.handleQuoteState('"', char, nextChar, i)) i++;
                    else if (isEscape && nextChar) i++; // 跳过转义字符
                    else this.current += char;
                    break;
                    
                case ParseState.LINE_COMMENT:
                    if (char === '\n') this.state = this.previousState;
                    else if (this.options.includeComments) this.current += char;
                    break;
                    
                case ParseState.BLOCK_COMMENT:
                    if (char === '*' && nextChar === '/') {
                        if (this.options.includeComments) this.current += '*/';
                        this.state = this.previousState;
                        i++;
                    } else if (this.options.includeComments) {
                        this.current += char;
                    }
                    break;
            }
        }
        
        // 重置缓冲区，保留未处理完的语句片段
        this.buffer = '';
    }

    private handleNormalState(char: string, nextChar: string): void {
        // 处理语句结束
        if (char === ';') {
            this.current += char;
            this.statements.push(this.current.trim());
            this.current = '';
            return;
        }
        
        // 处理字符串开始
        if (char === '\'') {
            this.current += char;
            this.state = ParseState.SINGLE_QUOTE;
            return;
        }
        
        if (char === '"') {
            this.current += char;
            this.state = ParseState.DOUBLE_QUOTE;
            return;
        }
        
        // 处理注释开始
        if (char === '-' && nextChar === '-') {
            this.previousState = this.state;
            this.state = ParseState.LINE_COMMENT;
            if (this.options.includeComments) this.current += '--';
            return;
        }
        
        if (char === '/' && nextChar === '*') {
            this.previousState = this.state;
            this.state = ParseState.BLOCK_COMMENT;
            if (this.options.includeComments) this.current += '/*';
            return;
        }
        
        // 普通字符
        this.current += char;
    }

    private handleQuoteState(quote: string, char: string, nextChar: string, index: number): boolean {
        if (char === quote) {
            this.current += char;
            
            // 处理转义引号
            if (nextChar === quote) {
                this.current += quote;
                return true;
            }
            
            this.state = ParseState.NORMAL;
            return false;
        }
        
        return false;
    }
}

/**
 * 创建SQL文件解析流
 * @param options 解析选项
 * @returns Transform流
 */
export function createSQLParser(options?: ParserOptions): Transform {
    const processor = new SQLStatementProcessor(options);
    return new SQLStreamReader(processor);
}

/**
 * 直接解析SQL字符串
 * @param sql SQL字符串
 * @param options 解析选项
 * @returns 解析后的语句数组
 */
export function parseSQLString(sql: string, options?: ParserOptions): string[] {
    const processor = new SQLStatementProcessor(options);
    processor.processChunk(sql);
    return processor.finalize();
}

